package controllers

import (
	"github.com/gin-gonic/gin"
	"golang.org/x/crypto/bcrypt"
	"library-system/config"
	"library-system/models"
	"library-system/utils"
	"math"
	"strconv"
)

type UserController struct{}

// 注册
func (uc *UserController) Register(c *gin.Context) {
	var user models.User
	if err := c.ShouldBindJSON(&user); err != nil {
		utils.Error(c, utils.ErrorCode, "请求参数有误")
		return
	}

	const MinPasswordLength = 6
	if len(user.Password) < MinPasswordLength {
		utils.Error(c, utils.ErrorCode, "密码长度至少6位")
		return
	}

	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
	if err != nil {
		utils.Error(c, utils.ErrorCode, "密码加密失败")
		return
	}

	user.Password = string(hashedPassword)
	if result := config.DB.Create(&user); result.Error != nil {
		utils.Error(c, utils.ErrorCode, "注册失败")
		return
	}

	//c.JSON(http.StatusCreated, user)
	utils.Success(c, "", gin.H{"user": user})
}

// 登录
func (uc *UserController) Login(c *gin.Context) {
	var req struct {
		Username string `json:"username" binding:"required"`
		Password string `json:"password" binding:"required,min=6"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.Error(c, utils.ErrorCode, "请求参数有误")
		return
	}

	var user models.User
	if err := config.DB.Where("username = ?", req.Username).First(&user).Error; err != nil {
		utils.Error(c, utils.ErrorCode, "用户不存在")
		return
	}

	if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password)); err != nil {
		utils.Error(c, utils.ErrorCode, "密码错误")
		return
	}

	token, err := utils.GenerateToken(user.ID, user.Role)
	if err != nil {
		utils.Error(c, utils.ErrorCode, "令牌生成失败")
		return
	}
	utils.Success(c, "", gin.H{"token": token})
}

// 获取用户集合
func (uc *UserController) ListUsers(c *gin.Context) {
	if _, err := strconv.Atoi(c.Query("page")); err != nil {
		utils.Error(c, utils.ErrorCode, "参数page必须是整数")
		return
	}
	if _, err := strconv.Atoi(c.Query("pageSize")); err != nil {
		utils.Error(c, utils.ErrorCode, "参数pageSize必须是整数")
		return
	}
	// 1. 获取分页参数（默认为 page=1, pageSize=10）
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10"))

	// 2. 参数校验（防止非法值）
	if page < 1 {
		page = 1
	}
	if pageSize < 1 || pageSize > 100 { // 限制每页最多100条
		pageSize = 10
	}

	// 3. 计算偏移量和起始序号
	offset := (page - 1) * pageSize
	startIndex := (page-1)*pageSize + 1 // 当前页第一条数据的序号

	var users []models.User
	var total int64

	// 4. 查询总数
	if err := config.DB.Model(&models.User{}).Count(&total).Error; err != nil {
		utils.Error(c, utils.ServerErrorCode, "查询用户总数失败")
		return
	}

	// 5. 分页查询数据
	if err := config.DB.
		Select("id, username, role, created_at").
		Order("created_at desc").
		Offset(offset).
		Limit(pageSize).
		Find(&users).Error; err != nil {
		utils.Error(c, utils.ServerErrorCode, "查询用户列表失败")
		return
	}

	// 6. 格式化时间并构建响应数据
	var result []map[string]interface{}
	for i, user := range users {
		result = append(result, map[string]interface{}{
			"index":      startIndex + i, // 关键点：计算序号
			"id":         user.ID,
			"username":   user.Username,
			"role":       user.Role,
			"created_at": user.CreatedAt.Format("2006-01-02 15:04:05"),
		})
	}

	// 7. 返回分页响应结构
	utils.Success(c, "", gin.H{
		"list":        result,
		"page":        page,
		"pageSize":    pageSize,
		"total":       total,
		"total_pages": int(math.Ceil(float64(total) / float64(pageSize))),
	})
}

// 更新用户信息
func (uc *UserController) UpdateUser(c *gin.Context) {
	//实现更新逻辑
}

// 删除用户
func (uc *UserController) DeleteUser(c *gin.Context) {
	//实现删除用户逻辑
}
